
#include <cassert>
#include <iostream>
#include <mpi.h>
#include <vector>
using namespace std;

void extractSerial(vector<int> &vec, int num_proc) {
  for (int i = 0; i < num_proc; ++i) {
    if (i % 2 == 0)
      vec.push_back(i);
  }
}

int main(int argc, char **argv) {
  int my_rank, num_proc;
  MPI_Init(&argc, &argv);
  MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
  MPI_Comm_size(MPI_COMM_WORLD, &num_proc);
  //   if (my_rank == 0) {
  //     cout << "num process = " << num_proc << endl;
  //     MPI_Group world_group;
  //     MPI_Comm_group(MPI_COMM_WORLD, &world_group);
  //     int world_group_size;
  //     MPI_Group_size(world_group, &world_group_size);
  //     cout << "world_group_size = " << world_group_size << endl;

  //     vector<int> even;
  //     extractSerial(even, num_proc);

  //     MPI_Group odd_group;
  //     MPI_Group_excl(world_group, even.size(), even.data(), &odd_group);
  //     int odd_group_size;
  //     MPI_Group_size(odd_group, &odd_group_size);
  //     cout << "odd_group_size = " << odd_group_size << endl;

  //     MPI_Group_size(world_group, &world_group_size);
  //     cout << "world_group_size = " << world_group_size << endl;

  //     MPI_Group_free(&odd_group);
  //     MPI_Group_free(&world_group);
  //   }

  if (my_rank == 0) {
    cout << "num process = " << num_proc << endl;
  }
  MPI_Group world_group;
  MPI_Comm_group(MPI_COMM_WORLD, &world_group);
  int world_group_size;
  MPI_Group_size(world_group, &world_group_size);
  if (my_rank == 0) {
    cout << "world_group_size = " << world_group_size << endl;
  }

  vector<int> even;
  extractSerial(even, num_proc);

  MPI_Group odd_group;
  MPI_Group_excl(world_group, even.size(), even.data(), &odd_group);
  int odd_group_size;
  MPI_Group_size(odd_group, &odd_group_size);
  if (my_rank == 0) {
    cout << "odd_group_size = " << odd_group_size << endl;
  }

  MPI_Group_size(world_group, &world_group_size);
  if (my_rank == 0) {
    cout << "world_group_size = " << world_group_size << endl;
  }

  MPI_Group_free(&odd_group);
  MPI_Group_free(&world_group);

  MPI_Comm odd_comm;
  MPI_Comm_create(MPI_COMM_WORLD, odd_group, &odd_comm);

  MPI_Finalize();

  return 0;
}